#include "SkyDome.h"
#include "D3DUtil.h"
#include "Vertex.h"


SkyDome::SkyDome(IDirect3DDevice9 *device, float radius, int numTheta, int numPhi )
		: m_radius(radius), m_numTheta(numTheta), m_numPhi(numPhi),
		  m_device(device), m_vb(0), m_ib(0), m_numTriangles(0), m_numVertices(0)
{
	m_numVertices  = m_numTheta * m_numPhi * 6;
	m_numTriangles = m_numVertices / 2;
}

void SkyDome::Init()
{
	GenerateVertices();	
	ComputeTexture();
}

void SkyDome::Destory()
{
	d3dutil::Release<IDirect3DVertexBuffer9*>(m_vb);
	d3dutil::Release<IDirect3DIndexBuffer9*>(m_ib);
}

void SkyDome::Render()
{
	D3DXMATRIX W;
	D3DXMatrixIdentity(&W);
	m_device->SetTransform(D3DTS_WORLD, &W);
	m_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
	m_device->SetStreamSource(0, m_vb, 0, sizeof(Vertex));
	//m_device->SetIndices(m_ib);
	m_device->SetFVF(Vertex::FVF);
	m_device->SetMaterial(&d3dutil::WHITE_MTRL);
	//m_device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, m_numVertices, 0, m_numTriangles);
	m_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, m_numTriangles);
	m_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
}

void SkyDome::GenerateVertices()
{
	HRESULT hr;
	hr = m_device->CreateVertexBuffer(
		m_numVertices * sizeof(Vertex), 
		D3DUSAGE_WRITEONLY, 
		Vertex::FVF,
		D3DPOOL_MANAGED,
		&m_vb,
		0);

	hr = m_device->CreateIndexBuffer(
		m_numTriangles * 3 * sizeof(WORD),
		D3DUSAGE_WRITEONLY,
		D3DFMT_INDEX16,
		D3DPOOL_MANAGED,
		&m_ib,
		0);

	float  d2r = D3DX_PI / 180.f;
	int dtheta = 360 / m_numTheta;
	int dphi   = 90  / m_numPhi;	

	Vertex  *v = NULL;
	int count = 0;

	m_vb->Lock(0, 0, (void**)&v, 0);
	for (int phi = 0; phi < 90; phi += dphi)
	{
		for (int theta = 0; theta < 360; theta += dtheta)
		{
			v[count]._x = m_radius * sinf(phi * d2r) * cosf(theta * d2r);
			v[count]._y = m_radius * cosf(phi * d2r);
			v[count]._z = m_radius * sinf(phi * d2r) * sinf(theta * d2r);			
			count++;

			v[count]._x = m_radius * sinf((phi+dphi) * d2r) * cosf(theta * d2r);
			v[count]._z = m_radius * sinf((phi+dphi) * d2r) * sinf(theta * d2r);
			v[count]._y = m_radius * cosf((phi+dphi) * d2r);
			count++;

			v[count]._x = m_radius * sinf((phi+dphi) * d2r) * cosf((dtheta + theta) * d2r);
			v[count]._z = m_radius * sinf((phi+dphi) * d2r) * sinf((dtheta + theta) * d2r);
			v[count]._y = m_radius * cosf((phi+dphi) * d2r);
			count++;

			v[count]._x = m_radius * sinf(phi * d2r) * cosf(theta * d2r);
			v[count]._z = m_radius * sinf(phi * d2r) * sinf(theta * d2r);
			v[count]._y = m_radius * cosf(phi * d2r);
			count++;

			v[count]._x = m_radius * sinf(phi * d2r) * cosf((dtheta + theta) * d2r);
			v[count]._z = m_radius * sinf(phi * d2r) * sinf((dtheta + theta) * d2r);
			v[count]._y = m_radius * cosf(phi * d2r);
			count++;

			if (phi > -90 && phi < 90)
			{
				v[count]._x = m_radius * sinf((phi+dphi) * d2r) * cosf((dtheta + theta) * d2r);
				v[count]._z = m_radius * sinf((phi+dphi) * d2r) * sinf((dtheta + theta) * d2r);
				v[count]._y = m_radius * cosf((phi+dphi) * d2r);
				count++;
			}
		}
	}

	m_vb->Unlock();

	WORD*  indices = NULL;
	count = 0;

	int perRow = m_numTheta;
	m_ib->Lock(0, 0, (void**)&indices, 0);
	for(int i = 0; i < m_numPhi; i++)
	{
		for (int j = 0; j < m_numTheta;j++)
		{
			indices[count]   = i * perRow + j;
			indices[count+1] = (i+1) * perRow + j;
			indices[count+2] = i * perRow + j + 1;

			indices[count+3] = i * perRow + j;
			indices[count+4] = i * perRow + j + 1;
			indices[count+5] = (i+1) * perRow + j + 1;

			count += 6;
		}
	}

	m_ib->Unlock();
}

void SkyDome::ComputeTexture()
{

}